package aam230713

import (
	"encoding/json"
	"fmt"
)

type Player struct {
	Id       int    `json:"id"`
	Name     string `json:"name"`
	Number   int    `json:"number"`
	Position string `json:"position"`
}

func (item *Player) input() {
	fmt.Print("Name: ")
	_, _ = fmt.Scanln(&item.Name)
	fmt.Print("Number: ")
	_, _ = fmt.Scanln(&item.Number)
}

func (item *Player) output() {
	fmt.Println("ID: ", item.Id)
	fmt.Println("Name: ", item.Name)
	fmt.Println("Number: ", item.Number)
	fmt.Println("Position: ", item.Position)
}

type Goalkeeper struct {
	Player
	Saves int `json:"saves"`
}

func (item *Goalkeeper) input() {
	item.Player.input()
	item.Position = "goalkeeper"
	fmt.Print("Number of saves: ")
	_, _ = fmt.Scanln(&item.Saves)
}

func (item *Goalkeeper) output() {
	item.Player.output()
	fmt.Println("Number of saves: ", item.Saves)
}

type Fullback struct {
	Player
	Counters int `json:"counters"`
}

func (item *Fullback) input() {
	item.Player.input()
	item.Position = "fullback"
	fmt.Print("Number of counters: ")
	_, _ = fmt.Scanln(&item.Counters)
}

func (item *Fullback) output() {
	item.Player.output()
	fmt.Println("Number of counters: ", item.Counters)
}

type Forward struct {
	Player
	Goals int `json:"goals"`
}

func (item *Forward) input() {
	item.Player.input()
	item.Position = "forward"
	fmt.Print("Number of goals: ")
	_, _ = fmt.Scanln(&item.Goals)
}

func (item *Forward) output() {
	item.Player.output()
	fmt.Println("Number of goals: ", item.Goals)
}

type InputInterface interface {
	input()
}

type OutputInterface interface {
	output()
}

func showPlayers(stRoute string) error {
	var team []map[string]interface{}
	res := GetDecoded(DoRequest("GET", stRoute, "showPlayers", nil), &team)
	if !res {
		return fmt.Errorf("error decoding")
	}
	for _, player := range team {
		mapToPlayer(player).output()
		fmt.Println("||||||||||||||||")
	}
	return nil
}

func mapToPlayer(playerMap map[string]interface{}) OutputInterface {
	position := playerMap["position"].(string)
	var player OutputInterface
	if position == "goalkeeper" {
		player = &Goalkeeper{}
	} else if position == "fullback" {
		player = &Fullback{}
	} else {
		player = &Forward{}
	}
	playerJson, _ := json.Marshal(playerMap)
	_ = json.Unmarshal(playerJson, &player)
	return player
}

func addPlayer(stRoute string) error {
	fmt.Println("Enter position: 1 - Goalkeeper, 2 - Fullback, 3 - Forward")
	var i int
	if _, e := fmt.Scanf("%d\n", &i); e != nil || i < 1 || i > 3 {
		return fmt.Errorf("incorrect value")
	}
	var char InputInterface
	if i == 1 {
		char = &Goalkeeper{}
	} else if i == 2 {
		char = &Fullback{}
	} else {
		char = &Forward{}
	}
	char.input()

	var response map[string]interface{}
	res := GetDecoded(DoRequest("POST", stRoute, "addPlayer", char), &response)
	if !res {
		return fmt.Errorf("error decoding")
	}
	message, exists := response["message"]
	if !exists {
		return fmt.Errorf("error response")
	}
	fmt.Println(message)
	return nil
}

func editPlayer(stRoute string) error {
	fmt.Println("Enter Player ID to edit: ")
	var id int
	if _, e := fmt.Scanf("%d\n", &id); e != nil {
		return fmt.Errorf("incorrect value")
	}
	var response map[string]interface{}
	res := GetDecoded(DoRequest("GET", stRoute, "edit", map[string]int{"id": id}), &response)
	if !res {
		return fmt.Errorf("error decoding")
	}
	val, exists := response["message"]
	if exists {
		fmt.Println(val)
	} else {
		position, _ := response["position"]
		fmt.Println(position)
		var char InputInterface
		if position == "goalkeeper" {
			char = &Goalkeeper{Player: Player{Id: id}}
		} else if position == "fullback" {
			char = &Fullback{Player: Player{Id: id}}
		} else {
			char = &Forward{Player: Player{Id: id}}
		}
		char.input()
		res = GetDecoded(DoRequest("POST", stRoute, "edit", char), &response)
		if !res {
			return fmt.Errorf("error decoding")
		}
		message, exists := response["message"]
		if !exists {
			return fmt.Errorf("error response")
		}
		fmt.Println(message)
	}
	return nil
}

func deletePlayer(stRoute string) error {
	fmt.Println("Enter Player ID to delete: ")
	var id int
	if _, e := fmt.Scanf("%d\n", &id); e != nil {
		return fmt.Errorf("incorrect value")
	}
	var response map[string]interface{}
	res := GetDecoded(DoRequest("DELETE", stRoute, "delete", map[string]int{"id": id}), &response)
	if !res {
		return fmt.Errorf("error decoding")
	}
	message, exists := response["message"]
	if !exists {
		return fmt.Errorf("error response")
	}
	fmt.Println(message)
	return nil
}
